package com.itheima.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.constant.MessageConstant;
import com.itheima.dao.MenuDao;
import com.itheima.dao.UserDao;
import com.itheima.pojo.Menu;
import com.itheima.entity.PageResult;
import com.itheima.pojo.Menu;
import com.itheima.pojo.Role;
import com.itheima.pojo.User;
import com.itheima.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户服务接口实现类
 *
 * @author wangxin
 * @version 1.0
 */
@Service(interfaceClass = UserService.class)
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private JedisPool jedisPool;

    @Autowired
    private MenuDao menuDao;

    /**
     * 根据用户名查询数据用户信息
     *
     * @param username
     * @return
     */
    @Override
    public User findByUserName(String username) {
        return userDao.findByUserName(username);
    }

    @Override
    public List<Menu> findRoleByUsername(String username) {
        Jedis jedis = jedisPool.getResource();
        String menuListStr = jedis.get("MENU_LIST_" + username);
        if (menuListStr != null && menuListStr.length() > 0) {
            List<Menu> menuList = (List<Menu>) JSON.parse(menuListStr);
            return menuList;
        }
        List<Menu> menuList = userDao.findRoleByUsername(username);
        jedis.set("MENU_LIST_" + username, JSON.toJSONString(menuList));
        return menuList;
    }

    public List<User> findAll() {
        return userDao.findAll();
    }

    /**
     * 1.*用户分页查询
     */
    @Override
    public PageResult findPage(Integer currentPage, Integer pageSize, String queryString) {
        PageHelper.startPage(currentPage, pageSize);
        //2.需要分页的语句
        Page<User> checkGroupPage = userDao.selectByCondition(queryString);


        return new PageResult(checkGroupPage.getTotal(), checkGroupPage.getResult());
    }

    /**
     * 2.*添加用户
     */
    @Override
    public void add(User user, Integer[] roleIds) {
        //判断用户名是否已经存在
        List<User> userList = userDao.findAll();
        if (userList != null && userList.size() > 0) {
            for (User dbuser : userList) {
                if (dbuser.getUsername().equalsIgnoreCase(user.getUsername())) {
                    throw new RuntimeException(MessageConstant.ADD_USER_NAME_FAIL);
                }
            }
        }
        // 往用户表添加
        String password = user.getPassword();
        if(!StringUtils.isEmpty(password)){
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            String encode = bCryptPasswordEncoder.encode(password);
            user.setPassword(encode);
        }
        userDao.add(user);
        // 往用户表与角色表中间写记录
        setUserAndRole(user.getId(), roleIds);
    }

    /**
     * 2.1*添加用户时查询所有角色
     */
    @Override
    public List<Role> findAllRole() {
        return userDao.findAllRole();
    }

    /**
     * 2.2.*往用户表与角色表中间写记录
     */
    public void setUserAndRole(Integer userId, Integer[] roleIds) {
        if (roleIds != null && roleIds.length > 0) {
            for (Integer roleId : roleIds) {
                Map<String, Integer> map = new HashMap<>();
                map.put("userId", userId);
                map.put("roleId", roleId);
                // 在t_user_role添加记录
                userDao.setUserAndRole(map);
            }
        }
    }

    /**
     * 3.1*编辑用户-回显用户
     */
    @Override
    public User findById(Integer usreId) {
        return userDao.findById(usreId);
    }

    /**
     * 3.3*编辑用户-回显角色ids
     */
    @Override
    public List<Integer> findRoleIdsByUserId(Integer userId) {
        return userDao.findRoleIdsByUserId(userId);
    }

    /**
     * 3.4*编辑用户-提交用户信息
     */
    @Override
    public void edit(User user, Integer[] roleIds) {
        //判断用户名是否已经存在
        List<User> userList = userDao.findAll();
        if (userList != null && userList.size() > 0) {
            for (User dbuser : userList) {
                // 使用当前用户和其它用户进行对比
                if (!dbuser.getId().equals(user.getId())) {
                    if (dbuser.getUsername().equalsIgnoreCase(user.getUsername())) {
                        throw new RuntimeException(MessageConstant.ADD_USER_NAME_FAIL);
                    }
                }
            }
        }
        // 更新用户表 update
        userDao.updateUser(user);
        // 先删除用户表与角色表记录(中间表)
        userDao.deleteAssociationUserAndRole(user.getId());
        // 重新建立用户表与角色表关系(中间表)
        setUserAndRole(user.getId(), roleIds);

        // 更新redis中该用户对应的菜单列表
        Jedis jedis = jedisPool.getResource();
        String username = user.getUsername();
        // 从redis拿当前用户名对应的key的值.
        String menuListStr = jedis.get("MENU_LIST_" + username);
        // 如果不为空则更新一下redis,如果为空.则在redis中查不到.该用户第一次登录时,会去数据库中查,并缓存到redis中.
        if (menuListStr != null) {
            List<Menu> menuList = menuDao.queryParentMenu(username);
            // 根据父菜单和username再查询其子菜单
            Map<String, Object> map = new HashMap<>();
            if (menuList != null && menuList.size() > 0) {
                for (Menu menu : menuList) {
                    map.put("parentId", menu.getId());
                    map.put("username", username);
                    List<Menu> childrenList = menuDao.queryChildrenMenu(map);
                    menu.setChildren(childrenList);
                }
            }
            // 存入redis中
            jedis.set("MENU_LIST_" + username, JSON.toJSONString(menuList));
        }

    }

    /**
     * 4.*删除用户
     */
    @Override
    public void deleteById(Integer userId) {
        // 使用用户id，查询用户和角色中间表
        Integer count1 = userDao.findUserAndRoleCountByUserId(userId);
        // 存在数据
        if (count1 > 0) {
            throw new RuntimeException("当前用户和角色之间存在关联关系，不能删除");
        }
        // 删除用户
        userDao.deleteById(userId);
    }

    @Override
    public void checkLogin(String username) {
        int count = userDao.checkLogin(username);
        if(count > 0){

        }else {
            throw new RuntimeException();
        }
    }
}
